package my.rpc.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import my.rpc.common.bean.RpcRequest;
import my.rpc.common.bean.RpcResponse;
import my.rpc.common.codec.RpcDecoder;
import my.rpc.common.codec.RpcEncoder;

import java.net.SocketAddress;

/**
 * 客户端任务
 * @author fengbo
 * @date 2017/11/17
 */
class RpcClientTask {

    private final EventLoopGroup eventLoopGroup;

    RpcClientTask(EventLoopGroup eventExecutors) {
        this.eventLoopGroup = eventExecutors;
    }

    RpcClientHandler connect(SocketAddress socketAddress) {
        // 创建并初始化 Netty 客户端 Bootstrap 对象
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup)
                .option(ChannelOption.TCP_NODELAY, true)
                // 创建一个生产Channel的工厂，负责创建对应类型的Channel
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel channel) {
                        ChannelPipeline pipeline = channel.pipeline();
                        // 粘包处理
                        pipeline.addLast(new LengthFieldBasedFrameDecoder(65536, 0,
                                4));
                        pipeline.addLast(new RpcEncoder<>(RpcRequest.class));
                        pipeline.addLast(new RpcDecoder<>(RpcResponse.class));
                        pipeline.addLast(new RpcClientHandler());
                    }
                });
        // 连接 RPC 服务器
        return bootstrap.connect(socketAddress).syncUninterruptibly()
                .channel().pipeline().get(RpcClientHandler.class);
    }

}
